from mock import MagicMock, call
from common import utils
from cvirt.common.test import BaseTest
import uuid
from cvirt.manager.models import Instance, Datacenter, Cluster, Server, Storage,SecurityGroup, SecurityGroupIngressRule, Interface, Network
from cvirt.cnode.nwfilter import api

class TestNWfilterapi(BaseTest):
    def setUp(self):

        api.conn = MagicMock()
        api.conn.nwfilterDefineXML.return_value = True

        self.datacenter = Datacenter.objects.create(name='datacenter1')
        self.cluster = Cluster.objects.create(name='cluster1',datacenter=self.datacenter)
        self.host = Server.objects.create(ip="172.16.10.25",host_name='node1',password='s',port=22,arch="x86_64",
                                          os="ubuntu",hypervisor='kvm',memshare=False,cpu_type='amd',qemu_version="1.0",
                                          cluster=self.cluster,status = 2)

        self.instance = Instance.objects.create(name='vm1',uuid=uuid.uuid4(),host=self.host,status='pending',
                                                power_status=1,graphics_type='vnc')
        self.storage = Storage.objects.create(name='storage1',protocol='local',mount_point='/root/cvirt_vms',host='172.16.10.25',
                                              cluster = self.cluster,totalsize=1024,is_data=True)


        self.sgroup = SecurityGroup.objects.create(name='testg')
        self.rule = SecurityGroupIngressRule.objects.create(protocol='tcp',action='accept',direction='in',
                                                            dstportstart="3000",dstportend="8000",dstipfrom='172.16.10.26',
                                                            dstipto='172.16.10.56',priority="20",
                                                            group = self.sgroup)


        self.network = Network.objects.create(name='host-bridge',cidr="10.0.0.0/24",rundhcp=False,networktype=2,cluster=self.cluster)
        self.interface = Interface.objects.create(name='eth0',mac=utils.generate_mac(),model="e1000",instance = self.instance,network=self.network)

        self.interface.securitygroups.add(self.sgroup)
        self.interface.save()


    def test_refresh_group(self):
        api.refresh_secruity_group(self.sgroup)
        calls = [call('''<filter name="testg" chain="ipv4">
  <rule priority="20" action="accept" direction="in">
    <tcp dstipfrom="172.16.10.26" dstipto="172.16.10.56" dstportstart="3000" dstportend="8000"/>
  </rule>
</filter>
'''),call('''<filter name="nwfilter-vm1-eth0" chain="ipv4">
  <filterref filter="clean-traffic"/>
  <filterref filter="allow-dhcp"/>
  <filterref filter="testg"/>
  <rule priority="1000" action="drop" direction="inout">
    <all/>
  </rule>
</filter>
''')]
        api.conn.nwfilterDefineXML.assert_has_calls(calls)


    def test_refresh_instance_no_dhcp(self):
        api.refresh_filter_for_instance(self.instance)
        api.conn.nwfilterDefineXML.assert_called_with(
'''<filter name="nwfilter-vm1-eth0" chain="ipv4">
  <filterref filter="clean-traffic"/>
  <filterref filter="allow-dhcp"/>
  <filterref filter="testg"/>
  <rule priority="1000" action="drop" direction="inout">
    <all/>
  </rule>
</filter>
''')
    def test_refresh_instance_with_dhcp(self):
        self.network.update(dict(rundhcp=True))
        api.refresh_filter_for_instance(self.instance)
        api.conn.nwfilterDefineXML.assert_called_with(
'''<filter name="nwfilter-vm1-eth0" chain="ipv4">
  <filterref filter="clean-traffic"/>
  <filterref filter="allow-dhcp-server"/>
  <filterref filter="testg"/>
  <rule priority="1000" action="drop" direction="inout">
    <all/>
  </rule>
</filter>
''')
    def test_add_sgroup_to_instance(self):
        self.sgroup2 = SecurityGroup.objects.create(name='testg2')
        self.rule2 = SecurityGroupIngressRule.objects.create(protocol='tcp',action='accept',direction='in',
                                                            dstportstart="3000",dstportend="8000",dstipfrom='172.16.10.26',
                                                            dstipto='172.16.10.56',priority="20",
                                                            group = self.sgroup2)

        self.interface.securitygroups.add(self.sgroup2)
        self.interface.save()

        api.refresh_filter_for_instance(self.instance)
        api.conn.nwfilterDefineXML.assert_called_with(
'''<filter name="nwfilter-vm1-eth0" chain="ipv4">
  <filterref filter="clean-traffic"/>
  <filterref filter="allow-dhcp"/>
  <filterref filter="testg"/>
  <filterref filter="testg2"/>
  <rule priority="1000" action="drop" direction="inout">
    <all/>
  </rule>
</filter>
''')



    def test_add_rule_to_group(self):
        self.rule3 = SecurityGroupIngressRule.objects.create(protocol='all',action='accept',direction='in',
                                                            priority="20",
                                                            group = self.sgroup)
        api.refresh_secruity_group(self.sgroup)

        calls = [call('''<filter name="testg" chain="ipv4">
  <rule priority="20" action="accept" direction="in">
    <tcp dstipfrom="172.16.10.26" dstipto="172.16.10.56" dstportstart="3000" dstportend="8000"/>
  </rule>
  <rule priority="20" action="accept" direction="in">
    <all/>
  </rule>
</filter>
'''),call('''<filter name="nwfilter-vm1-eth0" chain="ipv4">
  <filterref filter="clean-traffic"/>
  <filterref filter="allow-dhcp"/>
  <filterref filter="testg"/>
  <rule priority="1000" action="drop" direction="inout">
    <all/>
  </rule>
</filter>
''')]
        api.conn.nwfilterDefineXML.assert_has_calls(calls)
